package com.pingan.springboot_es_api.controller;

import com.pingan.springboot_es_api.domain.*;
import com.pingan.springboot_es_api.exception.MyException;
import com.pingan.springboot_es_api.utils.FilterUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.Info;
import org.frameworkset.elasticsearch.ElasticSearchHelper;
import org.frameworkset.elasticsearch.client.ClientInterface;
import org.frameworkset.elasticsearch.client.ResultUtil;
import org.frameworkset.elasticsearch.entity.ESDatas;
import org.frameworkset.elasticsearch.entity.InnerSearchHits;
import org.frameworkset.elasticsearch.serial.ESInnerHitSerialThreadLocal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * Created by Kay on 2018/11/9
 */
@RestController
@Api(value = "this is swagger!")
@RequestMapping("/api")
public class SearchController {
    private static Logger logger = LoggerFactory.getLogger(SearchController.class);
    @PostMapping("/search")
    @ApiOperation(value = "根据条件搜索", notes = " note ")
    public Object SearchClient(@RequestBody Filters filters) throws Exception{
        Long beginTime = System.currentTimeMillis();
        ClientInfo clientInfo = new ClientInfo();
        List<Basic> basicslst = new ArrayList<>();
        List<Diagnosis> diagnoseslst = new ArrayList<>();
        List<Medical> medicalslst = new ArrayList<>();
        List<Exam> examslst = new ArrayList<>();
        List<Checkup> checkupslst = new ArrayList<>();
        List<Followup> followupslst = new ArrayList<>();
        Long beginFilter = System.currentTimeMillis();
        Map<String,Object> params = FilterUtil.FilterParam(filters);
        Long endFilter = System.currentTimeMillis();
        logger.info("参数处理时间 :" + (endFilter - beginFilter) + " ms");
        Long beginLoadES = System.currentTimeMillis();
        ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/queryDsl.xml");
        Long endLoadES = System.currentTimeMillis();
        logger.info("ES加载时间 :" + (endLoadES - beginLoadES) + " ms");

        try {
            Long beginGetES = System.currentTimeMillis();
            ESInnerHitSerialThreadLocal.setESInnerTypeReferences("diagnosis",Diagnosis.class);//指定inner查询结果对于
            ESInnerHitSerialThreadLocal.setESInnerTypeReferences("medical", Medical.class);
            ESInnerHitSerialThreadLocal.setESInnerTypeReferences("exam", Exam.class);
            ESInnerHitSerialThreadLocal.setESInnerTypeReferences("checkup", Checkup.class);
            ESInnerHitSerialThreadLocal.setESInnerTypeReferences("followup", Followup.class);
            ESDatas<Basic> clients = clientUtil.searchList("client_info/basic/_search", "searchClientInfo", params, Basic.class);
            Long endGetES = System.currentTimeMillis();
            logger.info("查询es得到返回原始返回时间:" + (endGetES - beginGetES) + " ms");
            Long beginReturnJson = System.currentTimeMillis();
            List<Basic> datas = clients.getDatas();
            if(datas == null)
            {
//                throw new MyException("no datas");
                return new ClientInfo();
            }
            for ( int i =0  ; i< datas.size(); i++){
                Basic basic = datas.get(i);
                basicslst.add(new Basic(basic.getParty_id(),
                        basic.getSex(),
                        basic.getMari_sts(),
                        basic.getNationality_code(),
                        basic.getProf_code(),
                        basic.getProvince(),
                        basic.getCity(),
                        basic.getClient_type(),
                        basic.getClient_name(),
                        basic.getAge(),
                        basic.getId_type(),
                        basic.getIdno(),
                        basic.getEducation(),
                        basic.getCreated_date(),
                        basic.getBirth_date(),
                        basic.getLast_modified_date(),
                        basic.getEtl_dt())) ;
                // 年龄 记录到 每个子表中
                Integer age = basic.getAge();

                // 子表 诊断表
                List<Diagnosis> diagnoses = ResultUtil.getInnerHits(basic.getInnerHits(), "diagnosis");

                if ( diagnoses == null)
                {
                }else
                {
//                    for(Diagnosis d  : diagnoses){
//                        d.setAge(age);
//                    }
                    diagnoseslst.addAll(diagnoses);
                    Map<String, InnerSearchHits> mhits = basic.getInnerHits().get("diagnosis");
                    clientInfo.setDiagnosisSize(clientInfo.getDiagnosisSize() +
                            (mhits.get("hits") == null? 0L : mhits.get("hits").getTotal())
                    );
                }

                // 处方信息表
                List<Medical> medicals = ResultUtil.getInnerHits(basic.getInnerHits(),"medical");
                if (  medicals == null)
                {

                }else
                {

//                    for(Medical d  : medicals){
//                        d.setAge(age);
//                    }
                    medicalslst.addAll(medicals);
//                    clientInfo.setMedicalSize(clientInfo.getMedicalSize() + basic.getInnerHits().get("medical").);
                    Map<String, InnerSearchHits> mhits = basic.getInnerHits().get("medical");
                    clientInfo.setMedicalSize(clientInfo.getMedicalSize() +
                            (mhits.get("hits") == null? 0L : mhits.get("hits").getTotal())
                    );
                }

                // 检查信息表
                List<Checkup> checkups = ResultUtil.getInnerHits(basic.getInnerHits(),"checkup");
                if (  checkups == null)
                {

                }else
                {

//                    for(Checkup d  : checkups){
//                        d.setAge(age);
//                    }
                    checkupslst.addAll(checkups);
//                    clientInfo.setMedicalSize(clientInfo.getMedicalSize() + basic.getInnerHits().get("medical").);
                    Map<String, InnerSearchHits> mhits = basic.getInnerHits().get("checkup");
                    clientInfo.setCheckupSize(clientInfo.getCheckupSize() +
                            (mhits.get("hits") == null? 0L : mhits.get("hits").getTotal())
                    );
                }

                // 随访信息表
                List<Followup> followups = ResultUtil.getInnerHits(basic.getInnerHits(),"followup");
                if (  followups == null)
                {

                }else
                {

//                    for(Followup d  : followups){
//                        d.setAge(age);
//                    }
                    followupslst.addAll(followups);
//                    clientInfo.setMedicalSize(clientInfo.getMedicalSize() + basic.getInnerHits().get("medical").);
                    Map<String, InnerSearchHits> mhits = basic.getInnerHits().get("followup");
                    clientInfo.setFollowupSize(clientInfo.getFollowupSize() +
                            (mhits.get("hits") == null? 0L : mhits.get("hits").getTotal())
                    );
                }

                // 体检信息表
                List<Exam> exams = ResultUtil.getInnerHits(basic.getInnerHits(),"exam");
                if (  exams == null)
                {

                }else
                {

//                    for(Exam d  : exams){
//                        d.setAge(age);
//                    }
                    examslst.addAll(exams);
                    Map<String, InnerSearchHits> mhits = basic.getInnerHits().get("exam");

                    clientInfo.setExamSize(clientInfo.getExamSize() +
                            (mhits.get("hits") == null? 0L : mhits.get("hits").getTotal())
                    );
                }
            }
            if(basicslst == null){   //  无命中
                System.out.println("no clientInfo ");
            }else
            {
                clientInfo.setBasics(basicslst);
                clientInfo.setDiagnoses(diagnoseslst);
                clientInfo.setMedicals(medicalslst);
                clientInfo.setExams(examslst);
                clientInfo.setCheckups(checkupslst);
                clientInfo.setFollowups(followupslst);
                clientInfo.setTotalSize(clients.getTotalSize());
                clientInfo.setTook(clients.getRestResponse().getTook());
            }
            Long endReturnJson = System.currentTimeMillis();
            logger.info("处理查询返回数据生产json 时间:" + (endReturnJson - beginReturnJson) + " ms");
            Long endTime = System.currentTimeMillis();
            logger.info("查询总时间:" + (endTime - beginTime) + " ms");
            clientInfo.setAlltook(endTime - beginTime);
            logger.info(" ======================= clients totalSize     : " + clientInfo.getTotalSize());
            logger.info(" ======================= clients diagnosisSize : " + clientInfo.getDiagnosisSize());
            logger.info(" ======================= clients medicalSize : " + clientInfo.getMedicalSize());
            logger.info(" ======================= clients examSize : " + clientInfo.getExamSize());
            logger.info(" ======================= clients checkupSize : " + clientInfo.getCheckupSize());
            logger.info(" ======================= clients followupSize : " + clientInfo.getFollowupSize());
            logger.info(" ======================= clients es took : " + clientInfo.getTook() + " ms");
            logger.info(" ======================= clients es alltook : " + clientInfo.getAlltook() + " ms");
            return clientInfo;
        }catch (Exception e){
            logger.error(e.getMessage());
            throw new MyException(e.getMessage());
        }
        finally{
            logger.info(" ======================= search filters : " +  filters.toString());
            logger.info(" ======================= params : " + params.toString());
            ESInnerHitSerialThreadLocal.clean();//清空inner查询结果对于雇员类型
        }
    }
}
